﻿using BehaviorModel.Block;
using BehaviorModel.Block.Generator;
using BehaviorModel.Block.RandomGenerator;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace BehaviorModel.XmlSerializer
{
    /// <summary>
    /// Class for Xml Serialization of Generator Block
    /// </summary>
    public class GeneratorXmlSerializer : IXmlSerializer
    {
        /// <summary>
        /// Serializes Generator to XElement
        /// </summary>
        /// <returns></returns>
        public XElement ToXElement(IBlock block)
        {
            if (block is Generator)
            {
                Generator generator = (Generator)block;
                XElement requestGeneratorElement;
                using (var memoryStream = new MemoryStream())
                {
                    using (TextWriter streamWriter = new StreamWriter(memoryStream))
                    {
                        Type type = generator.RequestGenerator.GetType();
                        var xmlSerializer = new System.Xml.Serialization.XmlSerializer(generator.RequestGenerator.GetType());
                        xmlSerializer.Serialize(streamWriter, generator.RequestGenerator);
                        requestGeneratorElement = XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
                    }
                }

                return new XElement(XmlSerializationConstants.GENERATOR_BLOCK,
                    new XElement(XmlSerializationConstants.START_TIME, generator.StartTime),
                    requestGeneratorElement,
                    new XElement(XmlSerializationConstants.GENERATOR_TYPE, generator.GeneratorType));
            }
            else
            {
                throw new ArgumentException();
            }

        }

        /// <summary>
        /// Deserializes XElement to Generator
        /// </summary>
        /// <param name="xElement"></param>
        /// <returns></returns>
        public IBlock FromXElement(XElement xElement)
        {
            Generator generator = new Generator();
            generator.StartTime = Int32.Parse(xElement.Element(XmlSerializationConstants.GENERATOR_BLOCK).Element(XmlSerializationConstants.START_TIME).Value);
            generator.GeneratorType = (RandomGeneratorType)Enum.Parse(typeof(RandomGeneratorType), xElement.Element(XmlSerializationConstants.GENERATOR_BLOCK).Element(XmlSerializationConstants.GENERATOR_TYPE).Value);
            IRandomGenerator requestGenerator;
            using (var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.Element(XmlSerializationConstants.GENERATOR_BLOCK).Element(generator.GeneratorType.ToString() + "RandomGenerator").ToString())))
            {
                var xmlSerializer = new System.Xml.Serialization.XmlSerializer(Type.GetType("BehaviorModel.Block.RandomGenerator." + generator.GeneratorType.ToString() + "RandomGenerator"));
                requestGenerator = (IRandomGenerator)xmlSerializer.Deserialize(memoryStream);
            };
            generator.RequestGenerator = requestGenerator;
            return generator;
        }
    }
}
